package edu.yctc.delivery.service.impl;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

import edu.yctc.delivery.constant.ResultCode;
import edu.yctc.delivery.dao.UserDAO;
import edu.yctc.delivery.entity.ResultDO;
import edu.yctc.delivery.entity.UserDO;
import edu.yctc.delivery.service.UserService;
import edu.yctc.delivery.utils.CommonUtil;
import edu.yctc.delivery.utils.SHA256Util;

/**
 * 
 * @description userService的实现
 * @author zyj qlq
 *
 */
@ComponentScan({"edu.yctc.delivery.dao"})
@Service("userService")
public class UserServiceImpl implements UserService {

    private final static Logger LOG = LoggerFactory.getLogger("serviceLogger");

    @Resource
    private UserDAO userDAO;

    @Override
    public ResultDO<UserDO> getUserDOById(long id) {
        if (id <= 0) {
            LOG.error("get userDO by id fail, parameter invalid, id={}", id);
            return new ResultDO<UserDO>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            UserDO userDO = userDAO.getUserDOById(id);
            if (userDO == null) {
                LOG.error("get userDO by id fail, no such user, id={}", id);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by id success, id={}", id);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by id error, id={}", id, e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Long> signin(UserDO userDO) {
        // 检验参数
        if (StringUtils.isBlank(userDO.getAccount()) || StringUtils.isBlank(userDO.getPassword())) {
            LOG.error("signin fail, parameter invalid, userDO={}", userDO);
            return new ResultDO<Long>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            UserDO check = null;
            // 如果是邮箱登陆
            if (CommonUtil.isEmailAddress(userDO.getAccount())) {
                check =
                    userDAO.getUserDOByEmailAndPassword(userDO.getAccount(), SHA256Util.SHA256(userDO.getPassword()));
                // 如果是电话登陆
            } else if (CommonUtil.isPhoneNumber(userDO.getAccount())) {
                check =
                    userDAO.getUserDOByPhoneAndPassword(userDO.getAccount(), SHA256Util.SHA256(userDO.getPassword()));
            } else {
                check =
                    userDAO.getUserDOByAccountAndPassword(userDO.getAccount(), SHA256Util.SHA256(userDO.getPassword()));
            }
            if (check == null) {
                LOG.error("signin fail, no such user, userDO={}", userDO);
                return new ResultDO<Long>(false, ResultCode.INCORRECT_NUMBER_OR_PASSWORD,
                    ResultCode.MSG_INCORRECT_NUMBER_OR_PASSWORD, null);
            }
            LOG.info("signin success, userDO={}", userDO);
            return new ResultDO<Long>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, check.getId());
        } catch (Exception e) {
            LOG.error("signin error, userDO={}", userDO, e);
            return new ResultDO<Long>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<UserDO> getUserDOByMail(String mail) {
        try {
            UserDO userDO = userDAO.getUserDOByEmail(mail);
            if (userDO == null) {
                LOG.error("get userDO by mail fail, no such user, mail={}", mail);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by mail success, mail={}", mail);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by mail error", e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<UserDO> getUserDOByPhone(String phone) {
        try {
            UserDO userDO = userDAO.getUserDOByPhone(phone);
            if (userDO == null) {
                LOG.error("get userDO by phone fail, no such user, mail={}", phone);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by phone success, mail={}", phone);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by phone error", e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Long> register(UserDO userDO) {
        // 检验参数
        if (StringUtils.isBlank(userDO.getAccount()) || StringUtils.isBlank(userDO.getPassword())) {
            LOG.error("register fail, parameter invalid, userDO={}", userDO);
            return new ResultDO<Long>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            UserDO check_account = null;
            // 检查账户是否存在
            check_account = userDAO.getUserDOByAccountAndPassword(userDO.getAccount(), userDO.getPassword());
            if (check_account != null) {
                LOG.error("register fail, user exists, userDO={}", userDO);
                return new ResultDO<Long>(false, ResultCode.USER_EXISTS, ResultCode.MSG_USER_EXISTS, null);
            }
            UserDO check_email = null;
            // 检查邮箱是否存在
            check_email = userDAO.getUserDOByEmail(userDO.getEmail());
            if (check_email != null) {
                LOG.error("register fail,email exists,userDO={}", userDO);
                return new ResultDO<Long>(false, ResultCode.USER_EXISTS, ResultCode.MSG_USER_EXISTS, null);
            }
            userDAO.insert(userDO);
            LOG.info("register success, userDO={}", userDO);
            return new ResultDO<Long>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);

        } catch (Exception e) {
            LOG.error("register error, userDO={}", userDO, e);
            return new ResultDO<Long>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Void> ChangePassword(UserDO userDO, String password) {
        // 检验参数
        if (StringUtils.isBlank(userDO.getAccount()) || StringUtils.isBlank(userDO.getPassword())
            || StringUtils.isBlank(password)) {
            LOG.error("modify password fail, parameter invalid, userDO={}", userDO);
            return new ResultDO<Void>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            userDO.setPassword(SHA256Util.SHA256(password));
            userDAO.update(userDO);
            LOG.info("modify password success, userDO={}", userDO);
            return new ResultDO<Void>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, null);
        } catch (Exception e) {
            LOG.error("modify password error, userDO={}", userDO, e);
            return new ResultDO<Void>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }

    }

    @Override
    public ResultDO<Void> updateMail(UserDO userDO, String mail) {
        // 检验参数
        if (StringUtils.isBlank(userDO.getAccount()) || StringUtils.isBlank(userDO.getPassword())) {
            LOG.error("modify password fail, parameter invalid, userDO={}", userDO);
            return new ResultDO<Void>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            userDAO.update(userDO);
            LOG.info("modify password success, userDO={}", userDO);
            return new ResultDO<Void>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, null);
        } catch (Exception e) {
            LOG.error("modify password error, userDO={}", userDO, e);
            return new ResultDO<Void>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }

    }

    @Override
    public ResultDO<UserDO> getUserDOByAccount(String account) {
        try {
            UserDO userDO = userDAO.getUserDOByAccount(account);
            if (userDO == null) {
                LOG.error("get userDO by account fail, no such account, number={}", account);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by account success, account={}", account);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by account error, account={}", account, e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Void> updatePhone(UserDO userDO, String phone) {
        try {
            UserDO userDOTemp = userDAO.getUserDOById(userDO.getId());
            if (userDOTemp == null) {
                LOG.info("user wrong, userDO={}, phone={}", userDO, phone);
                return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
            }
            userDOTemp.setPhone(phone);
            userDAO.update(userDOTemp);
            LOG.info("update phone success, userDO={}, phone={}", userDO, phone);
            return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
        } catch (Exception e) {
            LOG.info("update phone error, userDO={}, phone={}", userDO, phone);
            return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
        }

    }

}
